package com.binguo.thirdPay.hzShiMing;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binguo.model.model.Customer;
import com.binguo.model.model.ShimingkaOrder;
import com.binguo.model.model.Shop;
import com.binguo.model.repository.ShimingkaOrderRepository;
import com.binguo.model.repository.ShopRepository;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuritian
 * @Title: HZShiMingService
 * @ProjectName binguoDevelop
 * @Description: TODO
 * @date 2019-07-0310:57
 */
@Service
public class HZShiMingService {
    private static Logger logger = LoggerFactory.getLogger(HZShiMingService.class);
    //测试环境APPID
//    private static final String APPID = "INTERNET_122856565296527";

    //上线环境APPID
    private static final String APPID = "INTERNET_219984936805240";

    //测试充值APPID
//    private static final String RECHARGE_APPID = "200000000012";

    //上线充值APPID
    private static final String RECHARGE_APPID = "100000000035";

    //测试环境商户号
//    private static final String MERCODE = "421101";

    private static final String VERSION = "1.0.0";

    //测试环境URL
//    private static final String URL = "http://115.236.162.166:28088/gateway";
    //上线环境URL
    private static final String URL = "https://hpay.96225.com/openapi";

    @Resource
    ShimingkaOrderRepository shimingkaOrderRepository;

    @Resource
    ShopRepository shopRepository;


    public static void main(String[] args) {
        HZShiMingService hzShiMingService = new HZShiMingService();
        hzShiMingService.queryAcc("W15751860","33032819610063211","1");
        //hzShiMingService.queryIdent("46550B84");
    }

    public JSONObject queryIdent(String cardNo){
        Map<String, String> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("channel", "07");
        messageMap.put("cardNo", cardNo);
        messageMap.put("reqSeq", reqSeq);

        String messageMapStr = JSON.toJSONString(messageMap);
        JSONObject result = getRessultJson("queryIdent",messageMapStr,reqSeq);
        if (result != null) {
            result = result.getJSONObject("data");
            System.out.println(result.toJSONString());
        }else {
            return null;
        }
        return result;
    }

    public JSONObject queryAcc(String cardNo,
                               String certNo,
                               String cardKind){
        Map<String, String> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("channel", "07");
        messageMap.put("cardNo", cardNo);
        messageMap.put("certNo",certNo);
        messageMap.put("cardKind",cardKind);
        messageMap.put("reqSeq", reqSeq);

        String messageMapStr = JSON.toJSONString(messageMap);
        JSONObject result = getRessultJson("queryAcc",messageMapStr,reqSeq);
        if (result != null) {
            result = result.getJSONObject("data");
        }else {
            return null;
        }
        System.out.println(result.toJSONString());
        return result;
    }

    public JSONObject offlineConsumer(String cardNo,
                                      String orderNo,
                                      Integer cityAmount,
                                      Integer districtAmount,
                                      Integer privateAmount,
                                      Integer reductAmount,
                                      String terminalNo,
                                      String merCode,
                                      String reqSeq,
                                      String reqTransDate,
                                      String reqTransTime,
                                      String posseq,
                                      String icdata){
        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("cardNo", cardNo);
        messageMap.put("merCode",merCode);
        messageMap.put("orderNo",orderNo);
        messageMap.put("cityAmount",cityAmount);
        messageMap.put("districtAmount",districtAmount);
        messageMap.put("privateAmount",privateAmount);
        messageMap.put("reductAmount",reductAmount);
        messageMap.put("terminalNo",terminalNo);
        messageMap.put("reqTransDate",reqTransDate);
        messageMap.put("reqTransTime",reqTransTime);
        if (StringUtils.hasText(posseq)) {
            messageMap.put("posseq", posseq);
            messageMap.put("icdata", icdata);
        }

        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);


        JSONObject result = getRessultJson("offlineConsumer",messageMapStr,reqSeq);
        if (result != null) {
            String payResult = result.getString("data");
            result = new JSONObject();
            result.put("data",payResult);
            result.put("reqSeq",reqSeq);
            result.put("reqTransDate",reqTransDate);
            result.put("reqTransTime",reqTransTime);
            return result;
        }else {
            return null;
        }
    }

    public JSONObject faceQuery(String imageToken){
        Map<String, Object> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("imageToken",imageToken);
        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);
        JSONObject result = getRessultJson("faceQuery",messageMapStr,reqSeq);
        if (result != null) {
            result = result.getJSONObject("data");
        }else {
            return null;
        }
        return result;
    }

    public JSONObject faceConsumer(Customer customer,
                                   Integer cityAmount,
                                   Integer districtAmount,
                                   Integer privateAmount,
                                   Integer reductAmount,
                                   String orderNo,
                                   String terminalNo,
                                   String merCode,
                                   String reqSeq,
                                   String reqTransDate,
                                   String reqTransTime){
        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("cardNo",customer.getShopPaycardid());
        messageMap.put("certNo",customer.getIdcardNum());
        messageMap.put("imageToken",customer.getImageToken());
        messageMap.put("merCode",merCode);
        messageMap.put("orderNo",orderNo);
        messageMap.put("cityAmount",cityAmount);
        messageMap.put("districtAmount",districtAmount);
        messageMap.put("privateAmount",privateAmount);
        messageMap.put("reductAmount",reductAmount);
        messageMap.put("terminalNo",terminalNo);
        messageMap.put("reqTransDate",reqTransDate);
        messageMap.put("reqTransTime",reqTransTime);
        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);
        JSONObject result = getRessultJson("faceConsumer",messageMapStr,reqSeq);
        if (result != null) {
            String payResult = result.getString("data");
            result = new JSONObject();
            result.put("data",payResult);
            result.put("reqSeq",reqSeq);
            result.put("reqTransDate",reqTransDate);
            result.put("reqTransTime",reqTransTime);
            System.out.println(result.toJSONString());
            return result;
        }else {
            return null;
        }
    }

    public JSONObject refund(String originalSerialNo,
                             String originalTransDate,
                             String originalTransTime,
                             String orderNo,
                             Integer amount,
                             String mercode){
        Date now = new Date();
        SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat time = new SimpleDateFormat("HHmmss");
        Map<String, Object> messageMap = new HashMap<>();


        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("merCode",mercode);
        messageMap.put("orderNo",orderNo);
        messageMap.put("amount",amount);
        String reqTransDate = date.format(now);
        String reqTransTime = time.format(now);
        messageMap.put("reqTransDate",reqTransDate);
        messageMap.put("reqTransTime",reqTransTime);
        messageMap.put("originalSerialNo",originalSerialNo);
        messageMap.put("originalTransDate",originalTransDate);
        messageMap.put("originalTransTime",originalTransTime);
        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);
        JSONObject result = getRessultJson("refund",messageMapStr,reqSeq);
        if (result != null) {
            String payResult = result.getString("data");
            result = new JSONObject();
            result.put("data",payResult);
            result.put("reqSeq",reqSeq);
            result.put("reqTransDate",reqTransDate);
            result.put("reqTransTime",reqTransTime);
            return result;
        }else {
            return null;
        }
    }

    public JSONObject queryTransSeq(String originalSerialNo,String orderNo,String mercode){
        Map<String, Object> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("orderNo",orderNo);
        messageMap.put("merCode",mercode);
        messageMap.put("originalSerialNo",originalSerialNo);
        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);
        JSONObject result = getRessultJson("queryTransSeq",messageMapStr,reqSeq);
        if (result != null) {
            result = result.getJSONObject("data");
        }else {
            return null;
        }
        return result;
    }

    public Boolean recharge(String cardNo,
                            String cardKind,
                            String txnamt,
                            String chmchntID){
        Map<String, Object> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("appid",RECHARGE_APPID);
        messageMap.put("appseq",reqSeq);
        messageMap.put("txntype",2010);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("cardkind",cardKind);
        paramMap.put("cardnumber",cardNo);
        paramMap.put("txnamt",txnamt);
        paramMap.put("chmchntid",chmchntID);
        paramMap.put("iccardno","");
        String param = JSON.toJSONString(paramMap);
        System.out.println("---------------");
        System.out.println(param);
        System.out.println("---------------");
        String signStr = "2010"+RECHARGE_APPID+reqSeq+param;
        messageMap.put("reqstr",param);
        try {
            messageMap.put("sign",RSAUtil.rsaRechargeSign(signStr));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        String messageStr = JSON.toJSONString(messageMap);
        JSONObject result = getRechargeRessultJson(messageStr);
        System.out.println(result.toJSONString());
        String respCode = result.getString("respcode");
        if(respCode.equals("00")){
            return true;
        }
        return false;
    }


    public Boolean faceBind(String imageBase64,
                            String certNo,
                            String name,
                            String cardNo,
                            String cardKind){
        Map<String, Object> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("certNo",certNo);
        messageMap.put("name",name);
        messageMap.put("cardKind",cardKind);
        messageMap.put("cardNo",cardNo);
        messageMap.put("image",imageBase64);
        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);
        JSONObject result = getRessultJson("faceBind",messageMapStr,reqSeq);
        if (result != null) {
            String facebindResult = result.getString("value");
            if (facebindResult.equals("value")){
                return true;
            }else{
                return false;
            }
        }else {
            return false;
        }
    }

    public Boolean cancelFaceBind(String certNo,
                                  String cardNo){
        Map<String, Object> messageMap = new HashMap<>();
        String reqSeq =  getReqSeq();
        messageMap.put("version", VERSION);
        messageMap.put("reqSeq", reqSeq);
        messageMap.put("channel", "07");
        messageMap.put("certNo",certNo);
        messageMap.put("cardNo",cardNo);
        String messageMapStr = JSON.toJSONString(messageMap);
        System.out.println(messageMapStr);
        JSONObject result = getRessultJson("cancelFaceBind",messageMapStr,reqSeq);
        if (result != null) {
            String facebindResult = result.getString("value");
            if (facebindResult.equals("value")){
                return true;
            }else{
                return false;
            }
        }else {
            return false;
        }
    }

    public void queryPayOrder(){
        Condition condition = new Condition(ShimingkaOrder.class);
        condition.or().andEqualTo("paystatus",0)
                .andEqualTo("status",3);
        List<ShimingkaOrder> shimingkaOrderList = shimingkaOrderRepository.findByCondition(condition);

        for (ShimingkaOrder shimingkaOrder : shimingkaOrderList){
            Shop shop = shopRepository.findById(shimingkaOrder.getShopId());
            String mercode = shop.getShimingkaShopid();
            JSONObject queryResult = queryTransSeq(shimingkaOrder.getOriginalserialno(),shimingkaOrder.getOrderno(),mercode);
            if (null == queryResult){
                continue;
            }
            String status = queryResult.getString("status");
            if (status.equals("2")){
                shimingkaOrder.setStatus(2);
                shimingkaOrderRepository.update(shimingkaOrder);
                continue;
            }else if (status.equals("1")){
                JSONObject refundResult = refund(shimingkaOrder.getOriginalserialno(),shimingkaOrder.getOriginaltransdate(),shimingkaOrder.getOriginaltranstime(),shimingkaOrder.getOrderno(),shimingkaOrder.getAmount(),mercode);
                if (null == refundResult){
                    continue;
                }else {
                    shimingkaOrder.setStatus(1);
                    shimingkaOrderRepository.update(shimingkaOrder);
                    String result = refundResult.getString("data");
                    ShimingkaOrder refundShimingkaOrder = new ShimingkaOrder();
                    refundShimingkaOrder.setAmount(shimingkaOrder.getAmount());
                    refundShimingkaOrder.setOrderno(shimingkaOrder.getOrderno());
                    refundShimingkaOrder.setOriginalserialno(refundResult.getString("reqSeq"));
                    refundShimingkaOrder.setOriginaltransdate(refundResult.getString("reqTransDate"));
                    refundShimingkaOrder.setOriginaltranstime(refundResult.getString("reqTransTime"));
                    refundShimingkaOrder.setPaystatus(1);
                    if (result.equals("3")){
                        refundShimingkaOrder.setStatus(3);
                    }else if (result.equals("5")){
                        refundShimingkaOrder.setStatus(2);
                    }else {
                        refundShimingkaOrder.setStatus(1);
                    }
                    shimingkaOrderRepository.save(refundShimingkaOrder);
                }
            }
        }
    }

    public void queryRefundOrder(){
        Condition condition = new Condition(ShimingkaOrder.class);
        condition.or().andEqualTo("paystatus",1)
                .andEqualTo("status",3);
        List<ShimingkaOrder> shimingkaOrderList = shimingkaOrderRepository.findByCondition(condition);
        for (ShimingkaOrder shimingkaOrder : shimingkaOrderList) {
            Shop shop = shopRepository.findById(shimingkaOrder.getShopId());
            String mercode = shop.getShimingkaShopid();
            JSONObject queryResult = queryTransSeq(shimingkaOrder.getOriginalserialno(), shimingkaOrder.getOrderno(),mercode);
            if (null == queryResult) {
                continue;
            }
            String status = queryResult.getString("status");
            if (status.equals("2")) {
                shimingkaOrder.setStatus(2);
                shimingkaOrderRepository.update(shimingkaOrder);
            } else if (status.equals("1")) {
                shimingkaOrder.setStatus(1);
                shimingkaOrderRepository.update(shimingkaOrder);
            }
        }

        condition = new Condition(ShimingkaOrder.class);
        condition.or().andEqualTo("paystatus", 1)
                .andEqualTo("status", 2);
        shimingkaOrderList = shimingkaOrderRepository.findByCondition(condition);

        for (ShimingkaOrder shimingkaOrder : shimingkaOrderList) {
            Shop shop = shopRepository.findById(shimingkaOrder.getShopId());
            String mercode = shop.getShimingkaShopid();
            JSONObject refundResult = refund(shimingkaOrder.getOriginalserialno(),shimingkaOrder.getOriginaltransdate(),shimingkaOrder.getOriginaltranstime(),shimingkaOrder.getOrderno(),shimingkaOrder.getAmount(),mercode);
            if (null == refundResult){
                continue;
            }else {
                String result = refundResult.getString("data");
                if (result.equals("3")){
                    shimingkaOrder.setStatus(3);
                }else if (result.equals("5")){
                    shimingkaOrder.setStatus(2);
                }else {
                    shimingkaOrder.setStatus(1);
                }
                shimingkaOrderRepository.update(shimingkaOrder);
            }
        }
    }

    private String getReqSeq(){
        return "YunPeng" + System.currentTimeMillis();
    }

    private JSONObject getRessultJson(String method,String messageMapStr,String reqSeq){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));

        logger.info(messageMapStr);
        Map<String, String> openMap = new HashMap<>();
        openMap.put("appId", APPID );
        openMap.put("method", method);
        openMap.put("sign_param", "appId,method,bizContent");
        openMap.put("bizContent",messageMapStr);
        try {
            openMap.put("sign", RSAUtil.rsaSign(openMap));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        String message = JSON.toJSONString(openMap);
        System.out.println(message);
        HttpEntity<String> entity = new HttpEntity<String>(message, headers);
        ResponseEntity<String> resp = restTemplate.postForEntity(URL, entity, String.class);
        String result = resp.getBody();
        logger.info(result);
        JSONObject json = JSONObject.parseObject(result);
        result = json.getString("success");
        Map<String, String> checkMap = new HashMap<>();
        if(result.equals("true")){
            checkMap.put("reqSeq", reqSeq);
            checkMap.put("sign_param", "success,value");
            checkMap.put("success", result);
            checkMap.put("value", json.getString("value"));
            checkMap.put("sign", json.getString("sign"));
            try {
                if (RSAUtil.rsaCheck(checkMap)){
                    if (method.equals("faceBind")){
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("value","true");
                        return jsonObject;
                    }else {
                        return JSONObject.parseObject(json.getString("value"));
                    }
                }else {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }else {
            if (method.equals("faceConsumer")){
                String respDesc = json.getString("respDesc");
                if (respDesc.equals("余额不足")){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("data","-1");
                    return jsonObject;
                }
            }
            return null;
        }
    }

    private JSONObject getRechargeRessultJson(String rechargeStr){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));
        System.out.println(rechargeStr);
        HttpEntity<String> entity = new HttpEntity<String>(rechargeStr, headers);
        //ResponseEntity<String> resp = restTemplate.postForEntity("http://115.236.162.166:8888/mcap/api/entra", entity, String.class);
        ResponseEntity<String> resp = restTemplate.postForEntity("https://sh.96225.com/mcap", entity, String.class);
        String result = resp.getBody();
        logger.info(result);
        JSONObject json = JSONObject.parseObject(result);
        return json;
    }
}
